package cc.magicjson.scenario.implement.module.jdbc.template.service.impl;

import cc.magicjson.scenario.implement.module.jdbc.template.entity.User;
import cc.magicjson.scenario.implement.module.jdbc.template.manager.BatchOperations;
import cc.magicjson.scenario.implement.module.jdbc.template.mapper.UserMapper;
import cc.magicjson.scenario.implement.module.jdbc.template.service.UserService;
import cc.magicjson.scenario.implement.module.jdbc.template.monitor.MethodStopWatch;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService{
    private final BatchOperations batchOperations;
    private final MethodStopWatch stopWatch;


    @Autowired
    private UserMapper userMapper;

    // 参数提取器
    private static final BatchOperations.BatchParameterExtractor<User> INSERT_PARAMS =
        user -> new Object[]{user.getName(), user.getEmail()};

    private static final BatchOperations.BatchParameterExtractor<User> UPDATE_PARAMS =
        user -> new Object[]{user.getEmail(), user.getName(), user.getId()};

    public UserServiceImpl(BatchOperations batchOperations,
                         MethodStopWatch stopWatch) {
        this.batchOperations = batchOperations;
        this.stopWatch = stopWatch;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchInsert(List<User> users) {
//        log.info("Starting batch insert for {} users", users.size());
//        if (log.isDebugEnabled()) {
//            users.forEach(user -> log.debug("User to insert: {}", user));
//        }

        return stopWatch.monitorWithTable("users", "batchInsert", () -> {
            int result = batchOperations.executeAutoBatch(
                users,
                "cc.magicjson.scenario.implement.module.jdbc.template.mapper.UserMapper.insertBySelectiveXml"
            );
            log.info("Batch insert completed, affected rows: {}", result);
            return result;
        });
    }

    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }


    @Override
    public User findById(Integer id) {
        return userMapper.findById(id);
    }


    @Override
    public int batchUpdate(List<User> users) {
        log.info("Starting batch update for {} users", users.size());
//        if (log.isDebugEnabled()) {
//            users.forEach(user -> log.debug("User to update: {}", user));
//        }

        return stopWatch.monitorWithTable("users", "batchUpdate", () -> {
            int result = batchOperations.executeAutoBatch(
                users,
                "cc.magicjson.scenario.implement.module.jdbc.template.mapper.UserMapper.updateBySelectiveXml"
            );
            log.info("Batch update completed, affected rows: {}", result);
            return result;
        });
    }

    @Override
    public int batchUpsert(List<User> users) {
        return stopWatch.monitorWithTable("users", "batchUpsert", () ->
            batchOperations.executeBatch(
                users,
                "user.upsert",
                INSERT_PARAMS
            )
        );
    }

    @Override
    public int batchInsertLarge(List<User> users) {
        return stopWatch.monitorWithTable("users", "batchInsertLarge", () ->
            batchOperations.executeLargeBatch(
                users,
                "user.batchInsert",
                INSERT_PARAMS,
                1000
            )
        );
    }
}
